From 160e6ad6f6fcc9c2819b2f8378763771f14c5320 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 5 Mar 2018 14:38:38 +0100 Subject: [PATCH] gdk: Split out GL texture Put GdkGLTexture into its own file and rename the API to gdk_gl_texture_foo() instead of gdk_texture_foo_for_gl(). Apart from naming, no actual code changes. --- gdk/gdk.h | 1 + gdk/gdkgltexture.c | 223 ++++++++++++++++++++++++++++++++++++++ gdk/gdkgltexture.h | 46 ++++++++ gdk/gdkgltextureprivate.h | 19 ++++ gdk/gdktexture.c | 203 +--------------------------------- gdk/gdktexture.h | 12 -- gdk/gdktextureprivate.h | 7 -- gdk/meson.build | 2 + gsk/gl/gskgldriver.c | 1 + gsk/gl/gskglrenderer.c | 11 +- gtk/gtkglarea.c | 12 +- 11 files changed, 305 insertions(+), 232 deletions(-) create mode 100644 gdk/gdkgltexture.c create mode 100644 gdk/gdkgltexture.h create mode 100644 gdk/gdkgltextureprivate.h diff --git a/gdk/gdk.h b/gdk/gdk.h index d1ee1b55ec..88656a4ca0 100644 --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include diff --git a/gdk/gdkgltexture.c b/gdk/gdkgltexture.c new file mode 100644 index 0000000000..e2f51c12d6 --- /dev/null +++ b/gdk/gdkgltexture.c @@ -0,0 +1,223 @@ +/* gdkgltexture.c + * + * Copyright 2016 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gdkgltextureprivate.h" + +#include "gdkcairo.h" +#include "gdktextureprivate.h" + +#include + +struct _GdkGLTexture { + GdkTexture parent_instance; + + GdkGLContext *context; + guint id; + + cairo_surface_t *saved; + + GDestroyNotify destroy; + gpointer data; +}; + +struct _GdkGLTextureClass { + GdkTextureClass parent_class; +}; + +G_DEFINE_TYPE (GdkGLTexture, gdk_gl_texture, GDK_TYPE_TEXTURE) + +static void +gdk_gl_texture_dispose (GObject *object) +{ + GdkGLTexture *self = GDK_GL_TEXTURE (object); + + if (self->destroy) + { + self->destroy (self->data); + self->destroy = NULL; + self->data = NULL; + } + + g_clear_object (&self->context); + self->id = 0; + + if (self->saved) + { + cairo_surface_destroy (self->saved); + self->saved = NULL; + } + + G_OBJECT_CLASS (gdk_gl_texture_parent_class)->dispose (object); +} + +static void +gdk_gl_texture_download (GdkTexture *texture, + guchar *data, + gsize stride) +{ + GdkGLTexture *self = GDK_GL_TEXTURE (texture); + cairo_surface_t *surface; + cairo_t *cr; + + surface = cairo_image_surface_create_for_data (data, + CAIRO_FORMAT_ARGB32, + texture->width, texture->height, + stride); + + cr = cairo_create (surface); + + if (self->saved) + { + cairo_set_source_surface (cr, self->saved, 0, 0); + cairo_paint (cr); + } + else + { + GdkWindow *window; + + window = gdk_gl_context_get_window (self->context); + gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0, + texture->width, texture->height); + } + + cairo_destroy (cr); + cairo_surface_finish (surface); + cairo_surface_destroy (surface); +} + +static void +gdk_gl_texture_class_init (GdkGLTextureClass *klass) +{ + GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + texture_class->download = gdk_gl_texture_download; + gobject_class->dispose = gdk_gl_texture_dispose; +} + +static void +gdk_gl_texture_init (GdkGLTexture *self) +{ +} + +GdkGLContext * +gdk_gl_texture_get_context (GdkGLTexture *self) +{ + return self->context; +} + +guint +gdk_gl_texture_get_id (GdkGLTexture *self) +{ + return self->id; +} + +/** + * gdk_gl_texture_release: + * @texture: a #GdkTexture wrapping a GL texture + * + * Releases the GL resources held by a #GdkTexture that + * was created with gdk_texture_new_for_gl(). + * + * The texture contents are still available via the + * gdk_texture_download() function, after this function + * has been called. + */ +void +gdk_gl_texture_release (GdkTexture *texture) +{ + GdkGLTexture *self; + GdkWindow *window; + cairo_t *cr; + + g_return_if_fail (GDK_IS_GL_TEXTURE (texture)); + + self = GDK_GL_TEXTURE (texture); + + g_return_if_fail (self->saved == NULL); + + self->saved = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + texture->width, texture->height); + + cr = cairo_create (self->saved); + + window = gdk_gl_context_get_window (self->context); + gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0, + texture->width, texture->height); + + cairo_destroy (cr); + + if (self->destroy) + { + self->destroy (self->data); + self->destroy = NULL; + self->data = NULL; + } + + g_clear_object (&self->context); + self->id = 0; +} + +/** + * gdk_gl_texture_new: + * @context: a #GdkGLContext + * @id: the ID of a texture that was created with @context + * @width: the nominal width of the texture + * @height: the nominal height of the texture + * @destroy: a destroy notify that will be called when the GL resources + * are released + * @data: data that gets passed to @destroy + * + * Creates a new texture for an existing GL texture. + * + * Note that the GL texture must not be modified until @destroy is called, + * which will happen when the GdkTexture object is finalized, or due to + * an explicit call of gdk_texture_release_gl(). + * + * Return value: A newly-created #GdkTexture + **/ +GdkTexture * +gdk_gl_texture_new (GdkGLContext *context, + guint id, + int width, + int height, + GDestroyNotify destroy, + gpointer data) +{ + GdkGLTexture *self; + + g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL); + g_return_val_if_fail (id != 0, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + + self = g_object_new (GDK_TYPE_GL_TEXTURE, + "width", width, + "height", height, + NULL); + + self->context = g_object_ref (context); + self->id = id; + self->destroy = destroy; + self->data = data; + + return GDK_TEXTURE (self); +} + diff --git a/gdk/gdkgltexture.h b/gdk/gdkgltexture.h new file mode 100644 index 0000000000..e5d24bd605 --- /dev/null +++ b/gdk/gdkgltexture.h @@ -0,0 +1,46 @@ +/* gdktexture.h + * + * Copyright 2016 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef __GDK_GL_TEXTURE_H__ +#define __GDK_GL_TEXTURE_H__ + +#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + + +GDK_AVAILABLE_IN_ALL +GdkTexture * gdk_gl_texture_new (GdkGLContext *context, + guint id, + int width, + int height, + GDestroyNotify destroy, + gpointer data); + +GDK_AVAILABLE_IN_ALL +void gdk_gl_texture_release (GdkTexture *texture); + + +G_END_DECLS + +#endif /* __GDK_GL_TEXTURE_H__ */ diff --git a/gdk/gdkgltextureprivate.h b/gdk/gdkgltextureprivate.h new file mode 100644 index 0000000000..180a99d064 --- /dev/null +++ b/gdk/gdkgltextureprivate.h @@ -0,0 +1,19 @@ +#ifndef __GDK_GL_TEXTURE_PRIVATE_H__ +#define __GDK_GL_TEXTURE_PRIVATE_H__ + +#include "gdkgltexture.h" + +#include "gdktextureprivate.h" + +G_BEGIN_DECLS + +#define GDK_TYPE_GL_TEXTURE (gdk_gl_texture_get_type ()) + +G_DECLARE_FINAL_TYPE (GdkGLTexture, gdk_gl_texture, GDK, GL_TEXTURE, GdkTexture) + +GdkGLContext * gdk_gl_texture_get_context (GdkGLTexture *self); +guint gdk_gl_texture_get_id (GdkGLTexture *self); + +G_END_DECLS + +#endif /* __GDK_GL_TEXTURE_PRIVATE_H__ */ diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c index dd3d0d7b60..8cfd0abc60 100644 --- a/gdk/gdktexture.c +++ b/gdk/gdktexture.c @@ -36,10 +36,8 @@ #include "gdktextureprivate.h" -#include "gdkinternals.h" #include "gdkcairo.h" - -#include +#include "gdkinternals.h" /** * SECTION:gdktexture @@ -429,159 +427,6 @@ gdk_pixbuf_texture_init (GdkPixbufTexture *self) { } -/* GdkGLTexture */ - - -struct _GdkGLTexture { - GdkTexture parent_instance; - - GdkGLContext *context; - guint id; - - cairo_surface_t *saved; - - GDestroyNotify destroy; - gpointer data; -}; - -struct _GdkGLTextureClass { - GdkTextureClass parent_class; -}; - -G_DEFINE_TYPE (GdkGLTexture, gdk_gl_texture, GDK_TYPE_TEXTURE) - -static void -gdk_gl_texture_dispose (GObject *object) -{ - GdkGLTexture *self = GDK_GL_TEXTURE (object); - - if (self->destroy) - { - self->destroy (self->data); - self->destroy = NULL; - self->data = NULL; - } - - g_clear_object (&self->context); - self->id = 0; - - if (self->saved) - { - cairo_surface_destroy (self->saved); - self->saved = NULL; - } - - G_OBJECT_CLASS (gdk_gl_texture_parent_class)->dispose (object); -} - -static void -gdk_gl_texture_download (GdkTexture *texture, - guchar *data, - gsize stride) -{ - GdkGLTexture *self = GDK_GL_TEXTURE (texture); - cairo_surface_t *surface; - cairo_t *cr; - - surface = cairo_image_surface_create_for_data (data, - CAIRO_FORMAT_ARGB32, - texture->width, texture->height, - stride); - - cr = cairo_create (surface); - - if (self->saved) - { - cairo_set_source_surface (cr, self->saved, 0, 0); - cairo_paint (cr); - } - else - { - GdkWindow *window; - - window = gdk_gl_context_get_window (self->context); - gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0, - texture->width, texture->height); - } - - cairo_destroy (cr); - cairo_surface_finish (surface); - cairo_surface_destroy (surface); -} - -static void -gdk_gl_texture_class_init (GdkGLTextureClass *klass) -{ - GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - texture_class->download = gdk_gl_texture_download; - gobject_class->dispose = gdk_gl_texture_dispose; -} - -static void -gdk_gl_texture_init (GdkGLTexture *self) -{ -} - -GdkGLContext * -gdk_gl_texture_get_context (GdkGLTexture *self) -{ - return self->context; -} - -guint -gdk_gl_texture_get_id (GdkGLTexture *self) -{ - return self->id; -} - -/** - * gdk_texture_release_gl: - * @texture: a #GdkTexture wrapping a GL texture - * - * Releases the GL resources held by a #GdkTexture that - * was created with gdk_texture_new_for_gl(). - * - * The texture contents are still available via the - * gdk_texture_download() function, after this function - * has been called. - */ -void -gdk_texture_release_gl (GdkTexture *texture) -{ - GdkGLTexture *self; - GdkWindow *window; - cairo_t *cr; - - g_return_if_fail (GDK_IS_GL_TEXTURE (texture)); - - self = GDK_GL_TEXTURE (texture); - - g_return_if_fail (self->saved == NULL); - - self->saved = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - texture->width, texture->height); - - cr = cairo_create (self->saved); - - window = gdk_gl_context_get_window (self->context); - gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0, - texture->width, texture->height); - - cairo_destroy (cr); - - if (self->destroy) - { - self->destroy (self->data); - self->destroy = NULL; - self->data = NULL; - } - - g_clear_object (&self->context); - self->id = 0; -} - /** * gdk_texture_new_for_pixbuf: * @pixbuf: a #GdkPixbuf @@ -676,52 +521,6 @@ gdk_texture_new_from_file (GFile *file, return texture; } -/** - * gdk_texture_new_for_gl: - * @context: a #GdkGLContext - * @id: the ID of a texture that was created with @context - * @width: the nominal width of the texture - * @height: the nominal height of the texture - * @destroy: a destroy notify that will be called when the GL resources - * are released - * @data: data that gets passed to @destroy - * - * Creates a new texture for an existing GL texture. - * - * Note that the GL texture must not be modified until @destroy is called, - * which will happen when the GdkTexture object is finalized, or due to - * an explicit call of gdk_texture_release_gl(). - * - * Return value: A newly-created #GdkTexture - **/ -GdkTexture * -gdk_texture_new_for_gl (GdkGLContext *context, - guint id, - int width, - int height, - GDestroyNotify destroy, - gpointer data) -{ - GdkGLTexture *self; - - g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL); - g_return_val_if_fail (id != 0, NULL); - g_return_val_if_fail (width > 0, NULL); - g_return_val_if_fail (height > 0, NULL); - - self = g_object_new (GDK_TYPE_GL_TEXTURE, - "width", width, - "height", height, - NULL); - - self->context = g_object_ref (context); - self->id = id; - self->destroy = destroy; - self->data = data; - - return GDK_TEXTURE (self); -} - /** * gdk_texture_get_width: * @texture: a #GdkTexture diff --git a/gdk/gdktexture.h b/gdk/gdktexture.h index ea04fc17cb..43bd9663e3 100644 --- a/gdk/gdktexture.h +++ b/gdk/gdktexture.h @@ -26,7 +26,6 @@ #include #include #include -#include G_BEGIN_DECLS @@ -56,17 +55,6 @@ GDK_AVAILABLE_IN_ALL GdkTexture * gdk_texture_new_from_file (GFile *file, GError **error); -GDK_AVAILABLE_IN_ALL -GdkTexture * gdk_texture_new_for_gl (GdkGLContext *context, - guint id, - int width, - int height, - GDestroyNotify destroy, - gpointer data); - -GDK_AVAILABLE_IN_ALL -void gdk_texture_release_gl (GdkTexture *texture); - GDK_AVAILABLE_IN_ALL int gdk_texture_get_width (GdkTexture *texture); GDK_AVAILABLE_IN_ALL diff --git a/gdk/gdktextureprivate.h b/gdk/gdktextureprivate.h index c6cab7801d..f9e5fbe908 100644 --- a/gdk/gdktextureprivate.h +++ b/gdk/gdktextureprivate.h @@ -44,13 +44,6 @@ void gdk_texture_clear_render_data (GdkTexture gpointer gdk_texture_get_render_data (GdkTexture *self, gpointer key); -#define GDK_TYPE_GL_TEXTURE (gdk_gl_texture_get_type ()) - -G_DECLARE_FINAL_TYPE (GdkGLTexture, gdk_gl_texture, GDK, GL_TEXTURE, GdkTexture) - -GdkGLContext * gdk_gl_texture_get_context (GdkGLTexture *self); -guint gdk_gl_texture_get_id (GdkGLTexture *self); - G_END_DECLS #endif /* __GDK_TEXTURE_PRIVATE_H__ */ diff --git a/gdk/meson.build b/gdk/meson.build index 466e11ff41..760cad8b64 100644 --- a/gdk/meson.build +++ b/gdk/meson.build @@ -24,6 +24,7 @@ gdk_public_sources = files([ 'gdkgl.c', 'gdkglcontext.c', 'gdkglobals.c', + 'gdkgltexture.c', 'gdkkeys.c', 'gdkkeyuni.c', 'gdkmonitor.c', @@ -66,6 +67,7 @@ gdk_public_headers = files([ 'gdkframeclock.h', 'gdkframetimings.h', 'gdkglcontext.h', + 'gdkgltexture.h', 'gdkkeys.h', 'gdkkeysyms.h', 'gdkmonitor.h', diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index 6d1c417b77..a7a62a49e1 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -5,6 +5,7 @@ #include "gskdebugprivate.h" #include "gskprofilerprivate.h" #include "gdk/gdktextureprivate.h" +#include "gdk/gdkgltextureprivate.h" #include #include diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index c805fe7c76..ca8fe4a30e 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -11,12 +11,13 @@ #include "gskrendernodeprivate.h" #include "gskshaderbuilderprivate.h" #include "gskglglyphcacheprivate.h" -#include "gdk/gdktextureprivate.h" #include "gskglrenderopsprivate.h" #include "gskcairoblurprivate.h" #include "gskprivate.h" +#include "gdk/gdkgltextureprivate.h" + #include #include @@ -2573,10 +2574,10 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer, /* Render the actual scene */ gsk_gl_renderer_do_render (renderer, root, viewport, texture_id, 1); - texture = gdk_texture_new_for_gl (self->gl_context, - texture_id, - width, height, - NULL, NULL); + texture = gdk_gl_texture_new (self->gl_context, + texture_id, + width, height, + NULL, NULL); gsk_gl_renderer_clear_tree (self); return texture; diff --git a/gtk/gtkglarea.c b/gtk/gtkglarea.c index d7ad09c2d0..e44c68ef66 100644 --- a/gtk/gtkglarea.c +++ b/gtk/gtkglarea.c @@ -386,7 +386,7 @@ delete_one_texture (gpointer data) Texture *texture = data; if (texture->holder) - gdk_texture_release_gl (texture->holder); + gdk_gl_texture_release (texture->holder); if (texture->id != 0) { @@ -735,11 +735,11 @@ gtk_gl_area_snapshot (GtkWidget *widget, priv->texture = NULL; priv->textures = g_list_prepend (priv->textures, texture); - texture->holder = gdk_texture_new_for_gl (priv->context, - texture->id, - texture->width, - texture->height, - release_texture, texture); + texture->holder = gdk_gl_texture_new (priv->context, + texture->id, + texture->width, + texture->height, + release_texture, texture); gtk_snapshot_append_texture (snapshot, texture->holder, -- 2.30.2